home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 5
/
MacMania 5.toast
/
/
Internet software
/
NewsWatcher
/
NW Source
/
Source
/
binmandlg.c
< prev
next >
Wrap
Text File
|
1997-01-09
|
12KB
|
441 lines
/*----------------------------------------------------------------------------
binmandlg.c
This module presents the extract binaries manually dialog.
Copyright © 1994-1997, Northwestern University.
----------------------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "glob.h"
#include "binmandlg.h"
#include "biglist.h"
#include "strutil.h"
#include "drawutil.h"
#include "olddrag.h"
#include "dialog.h"
#include "memutil.h"
#include "newswatcher.h"
#define kExtractBinariesManuallyDlg 149
#define kLabelItem 3
#define kListItem 4
static BigListRef gList;
static TSubject **gSubjectArray;
static Handle gStrings;
static short gDragTarget;
static DragTrackingHandlerUPP gHandleTrackingUPP = nil;
static DragReceiveHandlerUPP gHandleReceiveUPP = nil;
static ModalFilterUPP gMyDialogFilterUPP = nil;
static UserItemUPP gDlgLabelUserItemUPP = nil;
static UserItemUPP gDlgListUserItemUPP = nil;
/*----------------------------------------------------------------------------
DrawItem
Draw one list item in the dialog.
Entry: theList = list ref = gList.
index = index of info in gSubjectArray.
*itemRect = item rectangle.
----------------------------------------------------------------------------*/
static void DrawItem (BigListRef theList, long index, Rect *itemRect)
{
Str255 str;
CStr255 subject;
FontInfo fontInfo;
strcpy(subject, *gStrings + (*gSubjectArray)[index].subjectOffset);
sprintf((char*)str, "%ld - %.240s", (*gSubjectArray)[index].number, subject);
c2pstr((char*)str);
TruncString(itemRect->right - itemRect->left, str, smTruncEnd);
GetFontInfo(&fontInfo);
MoveTo(itemRect->left, itemRect->top + fontInfo.ascent);
DrawString(str);
}
/*----------------------------------------------------------------------------
DlgLabelUserItem
A user item procedure to draw the label at the top of the dialg.
Entry: dlg = pointer to dialog.
item = item number.
----------------------------------------------------------------------------*/
static pascal void DlgLabelUserItem (DialogPtr dlg, short item)
{
Str255 label;
Handle itemHandle;
short itemType;
Rect box;
TextStyle savedStyle;
GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
GetPString(kStrExtractBinariesManuallyDlgLabel, label);
GetPortTextStyle(&savedStyle);
TextFont(systemFont);
TextSize(12);
TETextBox(label+1, label[0], &box, teForceLeft);
SetPortTextStyle(&savedStyle);
}
/*----------------------------------------------------------------------------
DlgListUserItem
A user item procedure to draw the list in the dialog.
Entry: dlg = pointer to dialog.
item = item number.
----------------------------------------------------------------------------*/
static pascal void DlgListUserItem (DialogPtr dlg, short item)
{
Handle itemHandle;
short itemType;
Rect box;
GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
FrameRect(&box);
BigLGetViewRect(gList, &box);
box.right -= 15;
EraseRect(&box);
BigLUpdate(gList);
}
/*----------------------------------------------------------------------------
MyDialogFilter
Our dialog filter.
Entry: dlg = pointer to dialog.
ev = pointer to event record.
Exit: function result = true if event handled and item hit.
*itemHit = item number of item hit.
ev = pointer to possibly modified event record.
----------------------------------------------------------------------------*/
static pascal Boolean MyDialogFilter (DialogPtr dlg,
EventRecord *ev, short *itemHit)
{
short itemType;
Handle itemHandle;
Rect box;
Point where;
Boolean doubleClick;
if (ev->what == mouseDown) {
GetDialogItem(dlg, kListItem, &itemType, &itemHandle, &box);
InsetRect(&box, 1, 1);
where = ev->where;
GlobalToLocal(&where);
if (PtInRect(where, &box)) {
BigLClick(gList, where, ev->modifiers, &doubleClick);
ev->what = nullEvent;
return false;
}
} else if (ev->what == keyDown || ev->what == autoKey) {
if (BigLKey(gList, ev->message & charCodeMask, ev->modifiers)) {
ev->what = nullEvent;
return false;
}
}
return DialogFilter(dlg, ev, itemHit);
}
/*----------------------------------------------------------------------------
ClickLoop
The click loop function for the list. It initiates item drags.
Entry: theList = list ref = gList.
where = mouse location, in local coords.
modifiers = modifiers field from event record.
helperItem =
for shift-click, the item number of the item at the
other end of the selection range from the initially
clicked item (the "anchor" item for a shift-drag).
otherwise, the item number of the initially clicked item.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr ClickLoop (BigListRef theList, Point where, short modifiers,
long helperItem)
{
OSErr err = noErr;
DragReference dragRef;
Boolean haveDragRef = false;
RgnHandle dragRgn = nil;
EventRecord ev;
if ((modifiers & shiftKey) != 0 || (modifiers & cmdKey) != 0) {
return BigLDefaultClickLoop(theList, where, modifiers, helperItem);
}
LocalToGlobal(&where);
if (WaitMouseMoved(where)) {
err = NewDrag(&dragRef);
if (err != noErr) goto exit;
haveDragRef = true;
err = AddDragItemFlavor(dragRef, 1, kNewsWatcherSignature,
nil, 0, flavorSenderOnly);
if (err != noErr) goto exit;
BigLBuildSelectedItemsDragRegion(theList, &dragRgn);
gDragTarget = -1;
ev.what = mouseDown;
ev.message = 0;
ev.when = TickCount();
ev.where = where;
ev.modifiers = 0;
err = TrackDrag(dragRef, &ev, dragRgn);
if (err != noErr) goto exit;
DisposeRgn(dragRgn);
DisposeDrag(dragRef);
}
return noErr;
exit:
if (dragRgn != nil) DisposeRgn(dragRgn);
if (haveDragRef) DisposeDrag(dragRef);
return err;
}
/*----------------------------------------------------------------------------
HandleTracking
Drag Manager tracking handler for the dialog.
Entry: message = tracking message from Drag Manager.
wind = pointer to dialog.
handlerRefCon = reference constant (nil).
theDrag = drag reference.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static pascal OSErr HandleTracking (DragTrackingMessage message,
WindowPtr wind, void *handlerRefCon, DragReference theDrag)
{
Rect rView, contentRect;
Point where;
static Boolean canAcceptDrag;
OSErr err = noErr;
DragAttributes attributes;
GetDragAttributes(theDrag, &attributes);
if ((attributes & dragInsideSenderApplication) == 0) return noErr;
switch (message) {
case dragTrackingInWindow:
BigLGetViewRect(gList, &rView);
SetRect(&contentRect, rView.left, 0, rView.right-15, rView.bottom+15);
GetDragMouse(theDrag, &where, nil);
GlobalToLocal(&where);
if (PtInRect(where, &contentRect)) {
err = BigLHandleDragTracking(gList, theDrag, where);
if (err != noErr) goto exit;;
} else {
BigLTerminateDragTracking(gList, theDrag);
}
break;
case dragTrackingLeaveWindow:
BigLTerminateDragTracking(gList, theDrag);
break;
}
return noErr;
exit:
BigLTerminateDragTracking(gList, theDrag);
gDragErr = err;
return err;
}
/*----------------------------------------------------------------------------
HandleReceive
Drag Manager receive handler for the dialog.
Entry: wind = pointer to dialog.
handlerRefCon = reference constant (nil).
theDrag = drag reference.
Exit: function result = error code.
Note: No user interaction or network transactions are permitted in
this function.
----------------------------------------------------------------------------*/
static pascal OSErr HandleReceive (WindowPtr wind,
void *handlerRefCon, DragReference theDrag)
{
gDragTarget = BigLTerminateDragTracking(gList, theDrag);
if (gDragTarget < 0) return dragNotAcceptedErr;
return BigLMoveSelectedItems(gList, gList, gDragTarget, nil);
}
/*----------------------------------------------------------------------------
DoExtractBinariesManuallyDialog
Present the "Extract Binaries Manually" dialog.
Entry: wind = pointer to subject window.
Exit: function result = error code.
*articleList = handle to array of longword article numbers.
----------------------------------------------------------------------------*/
OSErr DoExtractBinariesManuallyDialog (WindowPtr wind, long ***articleList)
{
TWindow **info;
BigListRef subjectList;
long numSelected = 0, itema, itemb, index;
OSErr err = noErr;
DialogPtr dlg = nil;
short itemHit, fontNum, itemType, itemHeight, listHeight;
Handle itemHandle;
Rect rView;
long **artList = nil;
Boolean savedHiliteState;
if (gMyDialogFilterUPP == nil) gMyDialogFilterUPP =
NewModalFilterProc(MyDialogFilter);
if (gDlgLabelUserItemUPP == nil) gDlgLabelUserItemUPP =
NewUserItemProc(DlgLabelUserItem);
if (gDlgListUserItemUPP == nil) gDlgListUserItemUPP =
NewUserItemProc(DlgListUserItem);
gList = nil;
info = (TWindow**) GetWRefCon(wind);
subjectList = (**info).subjectList;
gSubjectArray = (**info).subjectArray;
gStrings = (**info).strings;
err = MyGetNewDialog(kExtractBinariesManuallyDlg, ok, cancel, &dlg);
if (err != noErr) return err;
DlgSetUserItem(dlg, kLabelItem, gDlgLabelUserItemUPP);
DlgSetUserItem(dlg, kListItem, gDlgListUserItemUPP);
if (gHaveDragMgr) {
if (gHandleTrackingUPP == nil) gHandleTrackingUPP =
NewDragTrackingHandlerProc(HandleTracking);
if (gHandleReceiveUPP == nil) gHandleReceiveUPP =
NewDragReceiveHandlerProc(HandleReceive);
err = InstallTrackingHandler(gHandleTrackingUPP, dlg, nil);
if (err != noErr) goto exit;
err = InstallReceiveHandler(gHandleReceiveUPP, dlg, nil);
if (err != noErr) goto exit;
}
SetPort(dlg);
GetFontNumber("\pMonaco", &fontNum);
TextFont(fontNum);
TextSize(9);
GetDialogItem(dlg, kListItem, &itemType, &itemHandle, &rView);
InsetRect(&rView, 1, 1);
itemHeight = GetFontLineHeight(dlg);
listHeight = rView.bottom - rView.top;
listHeight = listHeight/itemHeight*itemHeight;
rView.bottom = rView.top + listHeight;
savedHiliteState = ((WindowPeek)dlg)->hilited;
((WindowPeek)dlg)->hilited = true;
err = BigLNew(&rView, dlg, itemHeight, true, DrawItem, &gList);
((WindowPeek)dlg)->hilited = savedHiliteState;
if (err != noErr) goto exit;
BigLSetClickLoop(gList, gHaveDragMgr ? ClickLoop : OldExtractBinariesManuallyClickLoop);
InsetRect(&rView, -1, -1);
SetDialogItem(dlg, kListItem, itemType, itemHandle, &rView);
numSelected = BigLGetNumSelectedItems(subjectList);
err = BigLAddItems(gList, 0, numSelected);
if (err != noErr) goto exit;
itema = BigLGetFirstSelectedItem(subjectList);
itemb = 0;
while (itema >= 0) {
index = BigLGetData(subjectList, itema);
BigLSetData(gList, itemb, index);
itemb++;
itema = BigLGetNextSelectedItem(subjectList, itema+1);
}
MyModalDialog(dlg, gMyDialogFilterUPP, &itemHit);
if (itemHit == ok) {
err = MyNewHandle(numSelected * sizeof(long), &artList);
if (err != noErr) goto exit;
for (itemb = 0; itemb < numSelected; itemb++) {
index = BigLGetData(gList, itemb);
(*artList)[itemb] = (*gSubjectArray)[index].number;
}
}
BigLDispose(gList);
gList = nil;
if (gHaveDragMgr) {
RemoveTrackingHandler(gHandleTrackingUPP, dlg);
RemoveReceiveHandler(gHandleReceiveUPP, dlg);
}
err = DoClose(dlg);
if (err != noErr) return err;
if (itemHit == cancel) return userCanceledErr;
*articleList = artList;
return noErr;
exit:
if (gList != nil) BigLDispose(gList);
gList = nil;
if (dlg != nil) {
RemoveTrackingHandler(gHandleTrackingUPP, dlg);
RemoveReceiveHandler(gHandleReceiveUPP, dlg);
DoClose(dlg);
}
MyDisposeHandle(artList);
return err;
}